﻿//css_import Builder;
using System;
using System.Threading;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Build.CppBuild;
using Build;
namespace CppBuild
{
    public class ArmNoneEabiGccCppModule:GccCppModule
    {
        public enum Chips
        {
            Cortex_M0,
            Cortex_M0Plus,
            Cortex_M3,
            Cortex_M4,
            Cortex_M7,
        };
        public enum ArmThumbs
        {
            Arm,
            Thumb,
        };
        public enum FpuTypes
        {
            NoFpu,
            SoftFpu,
            HardFpu,
        }
        public enum OptimizationLevels
        {
            O0,
            O1,
            O2,
            O3,
            Os,
            Og,
        };
        //private OptimizationLevels _OptimizationLevel = OptimizationLevels.O0;
        //public OptimizationLevels OptimizationLevel { get { return _OptimizationLevel; } set { _OptimizationLevel = value; } }
        /*public ComplierTypes ComplierType
        {
            get
            {
                return ComplierTypes.GCC;    
            }
        }*/
        public override string Description
        {
            get
            {
                return "C# compile Script for use ARM-NONE-EABI-GCC.Version 0.2.161124\nCopyright (C) 2016 蒙塔基的钢蛋儿.E-Mail:408260925@qq.com\n";
            }
        }
        public Chips Chip { get; set; }
        public ArmThumbs ArmThumb { get; set; }
        public FpuTypes FpuType { get; set; }

        private string CcompilerToolFile;
        private string CxxCompilerToolFile;
        private string AsCompilerToolFile;
        private string ArToolFile;
        private string ldToolFile;
        private string ObjcopyToolFile;
        private string SizeToolFile;
        public override string Version
        {
            get
            {
                return "0.0.1";
            }
        }
        private string _toolsPath;
        /// <summary>
        /// tools path.
        /// </summary>
        public override string ToolsPath
        {
            get
            {
                return _toolsPath;
            }

            set
            {
                if (Directory.Exists(value) == false)
                    throw new DirectoryNotFoundException(value+":compiler Directory Not Found Exception");
                if(Directory.Exists(value + "/arm-none-eabi") == false)
                    throw new DirectoryNotFoundException(value + "/arm-none-eabi" + "\ncompiler Directory Not Found Exception");
                _toolsPath = value;
                if (Build.OsInfomation.OsHostType == Build.OsTypes.Windows)
                {
                    CcompilerToolFile = value + "/bin/arm-none-eabi-gcc.exe";
                    CxxCompilerToolFile = value + "/bin/arm-none-eabi-g++.exe";
                    AsCompilerToolFile = value + "/bin/arm-none-eabi-as.exe";
                    ArToolFile = value + "/bin/arm-none-eabi-ar.exe";
                    ldToolFile = value + "/bin/arm-none-eabi-ld.exe";
                    ObjcopyToolFile = value + "/bin/arm-none-eabi-objcopy.exe";
                    SizeToolFile = value + "/bin/arm-none-eabi-size.exe";
                }
               /* else
                {
                    CcompilerToolFile = value + "/bin/arm-none-eabi-gcc";
                    CxxCompilerToolFile = value + "/bin/arm-none-eabi-g++";
                    AsCompilerToolFile = value + "/bin/arm-none-eabi-as";
                    ArToolFile = value + "/bin/arm-none-eabi-ar";
                    ldToolFile = value + "/bin/arm-none-eabi-ld";
                    ObjcopyToolFile = value + "/bin/arm-none-eabi-objcopy";
                    SizeToolFile = value + "/bin/arm-none-eabi-size";
                }*/
                
            }
        }

        public bool IsOutHexFile { get; set; }
        public bool IsOutBinFile { get; set; }
        private OutFileTypes _OutFileType;
        public override OutFileTypes OutFileType
        {
            get
            {
                return _OutFileType;    
            }

            set
            {
                if (value == OutFileTypes.DynamicLibrary)
                    throw new Build.BuildException("参数设置错误，不可以编译动态库");
                _OutFileType = value;
            }
        }

        public ArmNoneEabiGccCppModule()
        {
            Console.WriteLine(this.Description);            
        }
        public override void Building()
        {
            //throw new NotImplementedException();
            string o = "-"+OptimizationType.ToString();
            string cs = "-std=" ;
            switch (CStandard)
            {
                case CStandardTypes.ISOC90:
                    cs += "c90";
                    break;
                case CStandardTypes.ISOC99:
                    cs += "c99";
                    break;
                case CStandardTypes.ISOC11:
                    cs += "c11";
                    break;
                case CStandardTypes.GNUC99:
                    cs += "gnu99";
                    break;
                case CStandardTypes.GNUC11:
                    cs += "gnu11";
                    break;
                default:
                    break;
            }
            string mcpu = "-mcpu=";
            switch (Chip)
            {
                case Chips.Cortex_M0:
                    mcpu += "cortex-m0";
                    break;
                case Chips.Cortex_M0Plus:
                    mcpu += "cortex-m0plus";
                    break;
                case Chips.Cortex_M3:
                    mcpu += "cortex-m3";
                    break;
                case Chips.Cortex_M4:
                    mcpu += "cortex-m4";
                    break;
                case Chips.Cortex_M7:
                    mcpu += "cortex-m7";
                    break;
                default:
                    break;
            }
            string armTub = "-m";
            switch (ArmThumb)
            {
                case ArmThumbs.Arm:
                    armTub += "arm";
                    break;
                case ArmThumbs.Thumb:
                    armTub += "thumb";
                    break;
                default:
                    break;
            }
            StringBuilder cinc = new StringBuilder();
            foreach (var item in CIncludePath)
            {
                cinc.Append("-I" + item + " ");
            }
            StringBuilder cdef = new StringBuilder();
            foreach (var item in CDefineList)
            {
                cdef.Append("-D" + item + " ");
            }
            string cc = "-c";
            foreach (var item in CFile)
            {
                Console.WriteLine("编译"+item+"文件:");
               RunCommand.Run(this.CcompilerToolFile, o,cs,mcpu,armTub,cinc.ToString(),cdef.ToString(), cc,item,"-o",OutBuildPath+"/"+item+".o");
               Console.WriteLine("\n------------------------------------------");
            } 
        }
        public override void BuildAll()
        {
            throw new NotImplementedException();
        }
        public override void Clean()
        {
            throw new NotImplementedException();
        }
    }
}
